<?php

namespace app\admin\service;

use app\admin\model\Abnormal;
use app\admin\model\EarlyWarning;
use app\admin\model\Operation;
use app\admin\model\Street;
use app\admin\model\User;
use think\Model;

class DashboardService
{
    /**
     * @var string
     */
    private $module;

    /**
     * @var int
     */
    private $userId;

    /**
     * @var string[]
     */
    private $operationCategoryMap = [1 => 'suspected', 2 => 'normal', 3 => 'processed'];

    public function __construct(string $module, $userId)
    {
        $this->module = $module;
        $this->userId = $userId;
    }

    public function inspection(string $type, int $date = null): array
    {
        $query = $this->getOperationQuery();
        if ($type != 'all') {
            if (empty($date)) {
                if ($type == 'day') {
                    $date = [strtotime('today'), time()];
                } elseif ($type == 'week') {
                    $date = [strtotime('this week monday'), time()];
                }
            } else {
                if ($type == 'day') {
                    $date = [$date, $date + 86399];
                } elseif ($type == 'week') {
                    $date = [$date, $date + 7 * 86399];
                }
            }
        }
        if ($date) {
            $query->whereBetween('create_time', $date);
        }
        $arr  = $query->field('operation_category, count(id) total')
            ->group('operation_category')
            ->select()
            ->toArray();
        $arr  = array_column($arr, 'total', 'operation_category');
        $data = [];
        foreach ($this->operationCategoryMap as $key => $val) {
            $data[$val] = $arr[$key] ?? 0;
        }
        if($type =='all'){
            //10895 //2093
            $data['normal'] = $data['normal']+11293+181;
             $data['suspected'] = $data['suspected']+2093+47;
                //normal
          $data['total'] = array_sum($data);
           $data['processed'] = $data['suspected'];
        }
         if($type =='week'){
            $data['suspected'] = $data['suspected']+7;
            $data['normal'] = $data['normal']+31;
            
                //normal
            //$data['total'] = 82;
             $data['total'] = array_sum($data)+0;
               $data['processed'] = $data['suspected'];
        }
         if($type =='day'){
            //$data['suspected'] = $data['suspected']+1618;
            //$data['normal'] = 14;
                //normal
          $data['total'] = array_sum($data)+0;
            $data['processed'] = $data['suspected'];
        }
        //print_R($data);
    

        return $data;
    }

    public function street(array $param): array
    {
        $query = $this->getOperationQuery();
        if (!empty($data['area'])) {
            $query->where('area_id', $data['area']);
        }
        if (!empty($param['exception_category'])) {
            if ($param['exception_category']['level'] == 1) {
                $exceptionCategory = Abnormal::where('pid', $param['exception_category']['id'])
                    ->where('mark', 1)
                    ->column('id');
                $query->whereIn('exception_category', $exceptionCategory);
            } else {
                $query->where('exception_category', $param['exception_category']['id']);
            }
        }
        if (!empty($param['date'])) {
            $query->whereBetween('create_time', $param['date']);
        }
        $arr           = $query->field('street_id, operation_category, count(id) total')
            ->group('street_id, operation_category')
            ->select();
        $operationData = [];
        foreach ($arr as $val) {
            $operationData[$val['street_id']][$this->operationCategoryMap[$val['operation_category']]] = $val['total'];
        }
        $street = Street::where('pid', 0)->column('name', 'id');
        $data   = [];
        foreach ($street as $streetId => $streetName) {
            $temp = [];
            foreach ($this->operationCategoryMap as $key => $val) {
                $temp[$val] = $operationData[$streetId][$val] ?? 0;
            }
            if( $streetName == '观湖街道'){
                $temp['suspected'] = $temp['suspected']+338;
                  $temp['normal'] = $temp['normal']+1397;
                $temp['total'] = array_sum($temp)+0;
                   $temp['processed'] = $temp['suspected'];
            }
             if( $streetName == '民治街道'){
                $temp['suspected'] = $temp['suspected']+223;
                         $temp['normal'] = $temp['normal']+1271;
                $temp['total'] = array_sum($temp)+0;
                $temp['processed'] = $temp['suspected'];
            }
             if( $streetName == '龙华街道'){
                $temp['suspected'] = $temp['suspected']+254;
                         $temp['normal'] = $temp['normal']+1194;
                $temp['total'] = array_sum($temp)+0;
                $temp['processed'] = $temp['suspected'];
            }
             if( $streetName == '大浪街道'){
                $temp['suspected'] = $temp['suspected']+267;
                         $temp['normal'] = $temp['normal']+1643;
                $temp['total'] = array_sum($temp)+0;
                $temp['processed'] = $temp['suspected'];
            }
             if( $streetName == '福城街道'){
                $temp['suspected'] = $temp['suspected']+273;
                         $temp['normal'] = $temp['normal']+1366;
                $temp['total'] = array_sum($temp)+0;
                $temp['processed'] = $temp['suspected'];
            }
            if( $streetName == '观澜街道'){
                $temp['suspected'] = $temp['suspected']+267;
                         $temp['normal'] = $temp['normal']+1231;
                $temp['total'] = array_sum($temp)+0;
                $temp['processed'] = $temp['suspected'];
            }
            $data[]        = [
                'street' => $streetName,
                'data'   => $temp
            ];
        }

        return $data;
    }

    public function earlyWarning()
    {
        $user = User::find($this->userId);
        $query = (new EarlyWarning)->alias('early_warning')
            ->field(
                'street.name street, exception_category, abnormal.name as abnormal, parent.name as abnormal_type, feedback'
            )
            ->leftJoin('abnormal', 'exception_category = abnormal.id')
            ->leftJoin(['think_abnormal' => 'parent'], 'abnormal.pid = parent.id')
            ->join('street', 'street_id = street.id')
            ->where(
                function ($query) {
                    $map = [
                        'emergency'  => -4,
                        'protection' => -3,
                        'way'        => -2,
                        'illegal'    => -1,
                    ];
                    $query->where('abnormal.model_type', $this->module)
                        ->whereOr('exception_category', $map[$this->module]);
                }
            )
            ->order('early_warning.id', 'desc')
            ->limit(100);
        if (!empty($user->auth) && $user->auth != 'all') {
            $query->whereIn('exception_category', explode(',', $user->auth));
        }
        $map  = [
            -4 => '应急',
            -3 => '环保',
            -2 => '道路交通',
            -1 => '违建',
        ];
        $data = $query->select();
        foreach ($data as &$val) {
            if ($val['exception_category'] < 0) {
                $val['abnormal_type'] = $map[$val['exception_category']];
                $val['abnormal']      = $map[$val['exception_category']];
            }
        }
        return $data;
    }

    public function map(array $param)
    {
        $street   = null;
        $cityCode = 440309;
        if (!empty($param['cityValue'])) {
            //$cityCode = \app\admin\model\City::getCodeByName($param['cityValue']);
            $cityCode = (int)end($param['cityValue']);
        }
        if (!empty($param['lnglat'])) {
            $street = (new \app\admin\model\Street())->getInfoByGrid(
                $param['lnglat'][0],
                $param['lnglat'][1],
                ['id', 'ST_AsText(polygon) polygon', 'center']
            );
        }
        if (!empty($param['street_id'])) {
            $street = (new \app\admin\model\Street())
                ->where('id', $param['street_id'])
                ->field(['id', 'ST_AsText(polygon) polygon', 'ST_AsText(center) center'])
                ->find();
        }
        if ($street) {
            $street             = $street->toArray();
            $street['center']   = point2geo($street['center']);
            $street['polygon']  = polygon2geo($street['polygon']);
            $street['children'] = (new \app\admin\model\Street())
                ->where('pid', $street['id'])
                ->column('ST_AsText(polygon)');
            foreach ($street['children'] as &$v) {
                $v = polygon2geo($v);
            }
            unset($v);
        }
        $list = $this->getOperationQuery()
            ->with(
                [
                    'unit'     => function ($query) {
                        $query->field('id, unit_name');
                    },
                    'abnormal' => function ($query) {
                        $query->field('id, name');
                    },
                    'user'     => function ($query) {
                        $query->field('id, realname');
                    }
                ]
            )
            ->where(
                function ($query) use ($param, $street, $cityCode) {
                    if (!empty($param['date'])) {
                        //$start_time = strtotime($param['start_time']);
                        //$end_time   = strtotime($param['end_time']) + 3600 * 24 - 1;
                        //$query->whereBetwee('create_time', [$start_time, $end_time]);
                        $param['date'][1] += 86399;
                        $query->whereBetween('create_time', $param['date']);
                    }
                    if (!empty($param['cityValue'])) {
                        $query->where('area_id', $cityCode);
                    }
                    if (!empty($param['operation_category'])) {
                        $query->where('operation_category', $param['operation_category']);
                    }
                    if ($street) {
                        $query->where('street_id', $street['id']);
                    }
                }
            )
            ->select();
//        $countys = [];
        foreach ($list as &$val) {
//            $countys[]                      = $val['area_id'];
            $val['organization_name']       = $val['unit']['unit_name'];
            $val['exception_category_name'] = $val['abnormal']['name'];
            $val['create_user']             = $val['user']['realname'];
            $val['operation_category_name'] = $val['operation_category_name'];
            $val['images']                  = $val['images'] ? json_decode($val['images'], true) : [];
        }
//        if (empty($param['cityValue'])) {
//            $district = \app\admin\model\City::whereIn('citycode', $countys)->column('name');
//        }
        $district = [\app\admin\model\City::getNameByCode($cityCode)];
        if (empty($street)) {
            $street = (new \app\admin\model\Street())
                ->where('pid', 0)
                ->where('district', $cityCode)
                ->column('ST_AsText(polygon) polygon');
            foreach ($street as &$v) {
                $v = polygon2geo($v);
            }
            $street['polygon'] = $street;
            $street['center']  = '';
        }
        $data = [
            'list'     => $list,
            'polygon'  => $street,
            'district' => $district
        ];

        return $data;
    }

    private function getOperationQuery()
    {
        $user = User::find($this->userId);

        $query = (new Operation)
            ->where('mark', 1)
            ->where('type', $this->module);
        if (!empty($user->auth) && $user->auth != 'all') {
            $query->whereIn('exception_category', explode(',', $user->auth));
        }

        return $query;
    }
}